#pragma once
/***********************************************************************************************
COPYRIGHT 2011 Mafahir Fairoze

This file is part of Neural++.
(Project Website : http://mafahir.wordpress.com/projects/neuralplusplus)

Neural++ is a free software. You can redistribute it and/or modify it under the terms of
the GNU General Public License as published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

Neural++ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License <http://www.gnu.org/licenses/> for more details.

***********************************************************************************************/

#include "../Helper.h"
#include "../Layer.h"
#include "INeighborhoodFunction.h"
#include "LatticeTopology.h"
#include "PositionNeuron.h"

namespace NeuralPlusPlus
	{
	namespace Core
		{
		namespace SOM
			{
			class PositionNeuron;
			class INeighborhoodFunction;
			/// <summary>
			/// Kohonen Layer is a layer containing position neurons.
			/// </summary>
			class KohonenLayer : public Layer
				{
				public: Size size;
				public: LatticeTopologyType topology;
				public: bool isRowCircular;
				public: bool isColumnCircular;
				public: PositionNeuron *winner;
				public: INeighborhoodFunction *neighborhoodFunction;

						/// <summary>
						/// Position Neuron indexer
						/// </summary>
				public: PositionNeuron* operator()(int x, int y);

						/// <summary>
						/// Creates a Kohonen layer with the specified size, topology and neighborhood function
						/// </summary>
				public: KohonenLayer(Size size, INeighborhoodFunction *neighborhoodFunction = NULL, LatticeTopologyType topology = LatticeTopologyType::Rectangular);

						/// <summary>
						/// Initializes all neurons and makes them ready to undergo fresh training.
						/// </summary>
				public: void Initialize() override;

						/// <summary>
						/// Runs all neurons in the layer and finds the winner
						/// </summary>
				public: void Run() override;

						/// <summary>
						/// All neurons and their are source connectors are allowed to learn. This method assumes a
						/// learning environment where inputs, outputs and other parameters (if any) are appropriate.
						/// </summary>
				public: void Learn(int currentIteration, int trainingEpochs) override;
				public: ~KohonenLayer();
				};
			}
		}
	}